<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            padding: 0;
            margin: 0;
            user-select: none;
        }
        .box{
            position: relative;
            height: 4000px;
            width: 100%;
        }
        .content{
            position: relative;
            margin-top: 500px;
            height: 3500px;
            width: 100%;
            background-color: #000;
        }
        .static{
            width: 100%;
            height: 100vh;
            position: sticky;
            top: 0;
            color: #fff;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .list{
            display: flex;
            justify-content: space-between;
            align-items: center;
            flex-wrap: wrap;
            width: 900px;
        }
        .item{
            width: 50px;
            height: 50px;
            border-radius: 10px;
            margin: 5% calc(100% / 8 - 85px);
        }
        .item:nth-child(3n+1){
            background-color: rgb(25, 206, 49);
        }
        .item:nth-child(3n+2){
            background-color: rgb(245, 196, 37);
        }
        .item:nth-child(3n+3){
            background-color: rgb(55, 58, 241);
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="content">
            <div class="static">
                <div class="list">
                    <div class="item" data-order="0"></div>
                    <div class="item" data-order="1"></div>
                    <div class="item" data-order="2"></div>
                    <div class="item" data-order="3"></div>
                    <div class="item" data-order="3"></div>
                    <div class="item" data-order="2"></div>
                    <div class="item" data-order="1"></div>
                    <div class="item" data-order="0"></div>
                    <div class="item" data-order="0"></div>
                    <div class="item" data-order="1"></div>
                    <div class="item" data-order="2"></div>
                    <div class="item" data-order="3"></div>
                    <div class="item" data-order="3"></div>
                    <div class="item" data-order="2"></div>
                    <div class="item" data-order="1"></div>
                    <div class="item" data-order="0"></div>
                </div>
            </div>
        </div>
    </div>

    <script>

        var content = document.querySelectorAll('.content')[0]
        var list = document.querySelectorAll('.list')[0]
        var items = document.querySelectorAll('.item')

        const animationMap = new Map()

        function createAnimation(scrollStart, scrollEnd, valueStart, valueEnd){
            return function (scroll){
                if (scroll <= scrollStart) {
                    return valueStart
                }
                if(scroll >= scrollEnd){
                    return valueEnd
                }
                return valueStart + (valueEnd - valueStart) * (scroll - scrollStart) / (scrollEnd - scrollStart)
            }
        }

        function getDomAnimation(scrollStart, scrollEnd, dom){

            scrollStart += dom.dataset.order * 500;

            const opacity = createAnimation(scrollStart, scrollEnd, 0, 1)

            const transformAnimation = createAnimation(scrollStart, scrollEnd, 0.5, 1)

            const xAnimation = createAnimation(scrollStart, scrollEnd, list.clientWidth / 2 - dom.offsetLeft - dom.clientWidth / 2, 0)

            const yAnimation = createAnimation(scrollStart, scrollEnd, list.clientHeight / 2 - dom.offsetTop - dom.clientHeight / 2, 0)


            const transform = function(scroll){
                return `translate(${yAnimation(scroll)}px) scale(${transformAnimation(scroll)})`
            }

            return {
                opacity,
                transform
            }
        }

        updateMap()

        function updateMap(){
            animationMap.clear()
            
            const play = content.getBoundingClientRect()
            const scrollStart = play.top + window.scrollY
            const scrollEnd = play.bottom + window.scrollY

            for(const item of items){
                animationMap.set(item, getDomAnimation(scrollStart, scrollEnd - 1000, item))
            }
        }

        updateStyle()

        function updateStyle(){
            const scroll = window.scrollY
            for(let [dom, value] of animationMap){
                for(const cssProp in value){
                    console.log(scroll);
                    dom.style[cssProp] = value[cssProp](scroll)
                }
            }
        }

        window.addEventListener('scroll', updateStyle)

    </script>
</body>
</html>